﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace ARCam3D.Imaging
{
    unsafe public class RGBImage : AbstractImage, ICloneable
    {
        private const PixelFormat pixelFormat = PixelFormat.Format24bppRgb;
        private const int bytesPerPixel = 3;
        private const int redOffset = 2;
        private const int greenOffset = 1;
        private const int blueOffset = 0;

        public static int BytesPerPixel
        {
            get { return bytesPerPixel; }
        }

        public static int RedOffset
        {
            get { return redOffset; }
        }

        public static int GreenOffset
        {
            get { return greenOffset; }
        }

        public static int BlueOffset
        {
            get { return blueOffset; }
        }

        private IntPtr dataPtr;

        public RGBImage(int width, int height)
            : base(width, height)
        {
            this.dataPtr = Marshal.AllocHGlobal(width * height * bytesPerPixel * sizeof(byte));
        }

        public RGBImage(int width, int height, IntPtr dataPtr)
            : base(width, height)
        {
            this.dataPtr = dataPtr;
        }

        ~RGBImage()
        {
            if (dataPtr != null && dataPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(dataPtr);
            }
        }

        public object Clone()
        {
            IntPtr dataCopyPtr = Marshal.AllocHGlobal(width * height * bytesPerPixel * sizeof(byte));
            Utils.Copy(dataCopyPtr, dataPtr, width * height * bytesPerPixel * sizeof(byte));
            return new RGBImage(width, height, dataCopyPtr);
        }

        public IntPtr DataPtr
        {
            get { return dataPtr; }
        }

        public RGBColor GetColor(int x, int y)
        {
            byte* dataPointer = (byte*)dataPtr.ToPointer() + (y * width + x) * bytesPerPixel;
            return new RGBColor(dataPointer[redOffset], dataPointer[greenOffset], dataPointer[blueOffset]);
        }

        public void SetColor(int x, int y, RGBColor color)
        {
            byte* dataPointer = (byte*)dataPtr.ToPointer() + (y * width + x) * bytesPerPixel;
            dataPointer[redOffset] = color.red;
            dataPointer[greenOffset] = color.green;
            dataPointer[blueOffset] = color.blue;
        }
    }
}
